<?php
require_once 'nOrm/TNOrmAdapter.inc';
require_once 'core/utils/THash.inc';

class TMSRole implements ISecuritySubject {
	const GUEST = 0;
	const CLIENT = 1;
	const MODERATOR = 2;
	const CONTENT_MANAGER = 4;
	const STOCK_MANAGER = 8;
	const CLIENT_MANAGER = 16;
	const ADMIN = 32;
	const EXTERNAL_SERVICE = 64;
	
	private $_id_;
	
	public function __construct($id){
		if (!($id == self::GUEST
			|| $id == self::CLIENT
			|| $id == self::MODERATOR
			|| $id == self::CONTENT_MANAGER
			|| $id == self::STOCK_MANAGER
			|| $id == self::CLIENT_MANAGER
			|| $id == self::ADMIN
			|| $id == self::EXTERNAL_SERVICE
			))
			throw new TCoreException(TCoreException::ERR_BAD_VALUE);
		$this->_id_ = $id;	
	}
	
	public function Guid(){
		return $this->_id_;
	}
	
	public static function RoleCodes(){
		return array(
			self::GUEST,
			self::CLIENT,
			self::MODERATOR,
			self::CONTENT_MANAGER,
			self::STOCK_MANAGER,
			self::CLIENT_MANAGER,
			self::ADMIN,
			self::EXTERNAL_SERVICE		
		);
	}
	
	public function __toString(){
		switch ($this->_id_){
			case self::ADMIN:return 'Administrator';break;
			case self::CLIENT:return 'Client';break;
			case self::GUEST:return 'Guest';break;
			case self::CLIENT_MANAGER:return 'Client manager';break;
			case self::CONTENT_MANAGER:return 'Content manager';break;
			case self::MODERATOR:return 'Moderator';break;
			case self::STOCK_MANAGER:return 'Stock manager';break;
			case self::EXTERNAL_SERVICE:return 'External service';break;
		}
	}
}


/**
 * User class
 * @author dkrasilnikov@gmail.com
 * @orm.table user(uid)
 * @orm.key Id
 * 
 * @property string $Password {@orm.scalar pwd}
 */
class TMSUser extends TNOrmObject implements ISecurityContext {
/**
 * @var int
 * @orm.scalar user.uid
 */	
	public $Id;
/**
 * @var string
 * @orm.scalar user.email
 */	
	public $Email;
	
/**
 * @var string
 * @orm.scalar user.login
 */	
	public $Login;
/**
 * @var int
 * @orm.scalar user.roles
 */	
	public $Roles;
/**
 * @var bool
 * @orm.scalar user.active
 */	
	public $Active;
	
/**
 * @var bool
 * @orm.scalar rehashed
 */
	public $Rehashed;
		
	protected $_orm_password_;
	private $_roles_;
	
	public function SetPasswordMD5($pwd){
		$this->_orm_password_ = THash::Apply($pwd,THash::MD5);
		$this->Rehashed = false;
	}
	
	public function CheckPasswordMD5($pwd){
		return $this->_orm_password_ == THash::Apply($pwd,THash::MD5);
	}
	
	public function SetPassword($pwd){
		$this->_orm_password_ = THash::Crypt($pwd,THash::BLOWFISH);
		$this->Rehashed = true;
	}
	
	public function CheckPassword($pwd){
		return THash::CheckHash($pwd, $this->_orm_password_);
	}	
		
	public function __set($nm,$value){
		switch ($nm){
			case 'AssignedRoles':{
				$v = 0;
				if (is_array($value)){
					foreach ($value as $role)
						$v = $v | (int)$role;
				} else if (is_int($value))
					$v = $value;
				if ($v & TMSRole::ADMIN)
					$v = $v | 30;	
				$this->Roles = $v;	
			}break;
			default:parent::__set($nm,$value);break;
		}
	}
	
	public function __get($nm){
		switch ($nm){
			case 'AssignedRoles':return $this->Cooperators();break;
			default:return parent::__get($nm);break;
		}
	}
	
	public function Guid(){
		return $this->Id;
	}
	
	public function Cooperators(){
		if (!is_array($this->_roles_)){
			$this->_roles_ = array();
			foreach (TMSRole::RoleCodes() as $code){
				if ($code & $this->Roles)
					$this->_roles_[$code] = new TMSRole($code);
			}
		}
		return $this->_roles_;
	}
	
	public function __toString(){
		return $this->Login?$this->Login:$this->Email;
	}
}